home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / execswp.com / EXECSWAP.ASM next >
Encoding:
Assembly Source File  |  1989-04-04  |  20.7 KB  |  431 lines

  1. ;EXECSWAP.ASM
  2. ;  Swap memory and exec another program
  3. ;  Copyright (c) 1988 TurboPower Software
  4. ;  May be used freely as long as due credit is given
  5.  
  6. ;  See EXECSWAP for details of version history
  7. ;  Version 1.1 - 3/15/89
  8. ;  Version 1.2 - 3/29/89
  9. ;-----------------------------------------------------------------------------
  10. DATA    SEGMENT WORD PUBLIC
  11.         EXTRN   BytesSwapped:DWORD      ;Bytes to swap to EMS/disk
  12.         EXTRN   EmsAllocated:BYTE       ;True when EMS allocated for swap
  13.         EXTRN   FileAllocated:BYTE      ;True when file allocated for swap
  14.         EXTRN   EmsHandle:WORD          ;Handle of EMS allocation block
  15.         EXTRN   FrameSeg:WORD           ;Segment of EMS page frame
  16.         EXTRN   FileHandle:WORD         ;Handle of DOS swap file
  17.         EXTRN   SwapName:BYTE           ;ASCIIZ name of swap file
  18.         EXTRN   PrefixSeg:WORD          ;Base segment of program
  19. DATA    ENDS
  20. ;-----------------------------------------------------------------------------
  21. CODE    SEGMENT WORD PUBLIC
  22.         ASSUME  CS:CODE,DS:DATA
  23.         PUBLIC  ExecWithSwap,FirstToSave
  24.         PUBLIC  AllocateSwapFile,DeallocateSwapFile
  25.         PUBLIC  DefaultDrive,DiskFree
  26.         PUBLIC  EmsInstalled,EmsPageFrame
  27.         PUBLIC  AllocateEmsPages,DeallocateEmsHandle
  28. ;-----------------------------------------------------------------------------
  29. FileAttr        EQU     6               ;Swap file attribute (hidden+system)
  30. EmsPageSize     EQU     16384           ;Size of EMS page
  31. FileBlockSize   EQU     32768           ;Size of a file block
  32. StkSize         EQU     128             ;Bytes in temporary stack
  33. lo              EQU     (WORD PTR 0)    ;Convenient typecasts
  34. hi              EQU     (WORD PTR 2)
  35. ofst            EQU     (WORD PTR 0)
  36. segm            EQU     (WORD PTR 2)
  37. ;-----------------------------------------------------------------------------
  38. ;Variables in CS
  39. EmsDevice       DB      'EMMXXXX0',0    ;Name of EMS device driver
  40. UsedEms         DB      0               ;1 if swapping to EMS, 0 if to file
  41. BytesSwappedCS  DD      0               ;Bytes to move during a swap
  42. EmsHandleCS     DW      0               ;EMS handle
  43. FrameSegCS      DW      0               ;Segment of EMS page window
  44. FileHandleCS    DW      0               ;DOS file handle
  45. PrefixSegCS     DW      0               ;Segment of base of program
  46. Status          DW      0               ;ExecSwap status code
  47. LeftToSwap      DD      0               ;Bytes left to move
  48. SaveSP          DW      0               ;Original stack pointer
  49. SaveSS          DW      0               ;Original stack segment
  50. PathPtr         DD      0               ;Pointer to program to execute
  51. CmdPtr          DD      0               ;Pointer to command line to execute
  52. ParasWeHave     DW      0               ;Paragraphs allocated to process
  53. CmdLine         DB      128 DUP(0)      ;Terminated command line passed to DOS
  54. Path            DB      64 DUP(0)       ;Terminated path name passed to DOS
  55. FileBlock1      DB      16 DUP(0)       ;FCB passed to DOS
  56. FileBlock2      DB      16 DUP(0)       ;FCB passed to DOS
  57. EnvironSeg      DW      0               ;Segment of environment for child
  58. CmdLinePtr      DD      0               ;Pointer to terminated command line
  59. FilePtr1        DD      0               ;Pointer to FCB file
  60. FilePtr2        DD      0               ;Pointer to FCB file
  61. TempStack       DB      StkSize DUP(0)  ;Temporary stack
  62. StackTop        LABEL   WORD            ;Initial top of stack
  63. ;-----------------------------------------------------------------------------
  64. ;Macros
  65. MovSeg          MACRO Dest,Src          ;Set one segment register to another
  66.         PUSH    Src
  67.         POP     Dest
  68.                 ENDM
  69.  
  70. MovMem          MACRO Dest,Src          ;Move from memory to memory via AX
  71.         MOV     AX,Src
  72.         MOV     Dest,AX
  73.                 ENDM
  74.  
  75. InitSwapCount   MACRO                   ;Initialize counter for bytes to swap
  76.         MovMem  LeftToSwap.lo,BytesSwappedCS.lo
  77.         MovMem  LeftToSwap.hi,BytesSwappedCS.hi
  78.                 ENDM
  79.  
  80. SetSwapCount    MACRO BlkSize           ;Return CX = bytes to move this block
  81.         LOCAL   FullBlk                 ;...and reduce total bytes left to move
  82.         MOV     CX,BlkSize              ;Assume we'll write a full block
  83.         CMP     LeftToSwap.hi,0         ;Is high word still non-zero?
  84.         JNZ     FullBlk                 ;Jump if so
  85.         CMP     LeftToSwap.lo,BlkSize   ;Low word still a block or more?
  86.         JAE     FullBlk                 ;Jump if so
  87.         MOV     CX,LeftToSwap.lo        ;Otherwise, move what's left
  88. FullBlk:SUB     LeftToSwap.lo,CX        ;Reduce number left to move
  89.         SBB     LeftToSwap.hi,0
  90.                 ENDM
  91.  
  92. NextBlock       MACRO SegReg, BlkSize   ;Point SegReg to next block to move
  93.         MOV     AX,SegReg
  94.         ADD     AX,BlkSize/16           ;Add paragraphs to next segment
  95.         MOV     SegReg,AX               ;Next block to move
  96.         MOV     AX,LeftToSwap.lo
  97.         OR      AX,LeftToSwap.hi        ;Bytes left to move?
  98.                 ENDM
  99.  
  100. EmsCall         MACRO FuncAH            ;Call EMM and prepare to check result
  101.         MOV     AH,FuncAH               ;Set up function
  102.         INT     67h
  103.         OR      AH,AH                   ;Error code in AH
  104.                 ENDM
  105.  
  106. DosCallAH       MACRO FuncAH            ;Call DOS subfunction AH
  107.         MOV     AH,FuncAH
  108.         INT     21h
  109.                 ENDM
  110.  
  111. DosCallAX       MACRO FuncAX            ;Call DOS subfunction AX
  112.         MOV     AX,FuncAX
  113.         INT     21h
  114.                 ENDM
  115.  
  116. InitSwapFile    MACRO
  117.         MOV     BX,FileHandleCS         ;BX = handle of swap file
  118.         XOR     CX,CX
  119.         XOR     DX,DX                   ;Start of file
  120.         DosCallAX 4200h                 ;DOS file seek
  121.                 ENDM
  122.  
  123. HaltWithError   MACRO Level             ;Halt if non-recoverable error occurs
  124.         MOV     AL,Level                ;Set errorlevel
  125.         DosCallAH 4Ch
  126.                 ENDM
  127.  
  128. MoveFast        MACRO                   ;Move CX bytes from DS:SI to ES:DI
  129.         CLD                             ;Forward
  130.         SHR     CX,1                    ;Convert to words
  131.         REP     MOVSW                   ;Move the words
  132.         RCL     CX,1                    ;Get the odd byte, if any
  133.         REP     MOVSB                   ;Move it
  134.                 ENDM
  135.  
  136. SetTempStack    MACRO                   ;Switch to temporary stack
  137.         MOV     AX,OFFSET StackTop      ;Point to top of stack
  138.         MOV     BX,CS                   ;Temporary stack in this code segment
  139.         CLI                             ;Interrupts off
  140.         MOV     SS,BX                   ;Change stack
  141.         MOV     SP,AX
  142.         STI                             ;Interrupts on
  143.                 ENDM
  144. ;-----------------------------------------------------------------------------
  145. ;function ExecWithSwap(Path, CmdLine : string) : Word;
  146. ExecWithSwap    PROC FAR
  147.         PUSH    BP
  148.         MOV     BP,SP                   ;Set up stack frame
  149.  
  150. ;Move variables to CS where we can easily access them later
  151.         MOV     Status,1                ;Assume failure
  152.         LES     DI,[BP+6]               ;ES:DI -> CmdLine
  153.         MOV     CmdPtr.ofst,DI
  154.         MOV     CmdPtr.segm,ES          ;CmdPtr -> command line string
  155.         LES     DI,[BP+10]              ;ES:DI -> Path
  156.         MOV     PathPtr.ofst,DI
  157.         MOV     PathPtr.segm,ES         ;PathPtr -> path to execute
  158.         MOV     SaveSP,SP               ;Save stack position
  159.         MOV     SaveSS,SS
  160.         MovMem  BytesSwappedCS.lo,BytesSwapped.lo
  161.         MovMem  BytesSwappedCS.hi,BytesSwapped.hi
  162.         MovMem  EmsHandleCS,EmsHandle
  163.         MovMem  FrameSegCS,FrameSeg
  164.         MovMem  FileHandleCS,FileHandle
  165.         MovMem  PrefixSegCS,PrefixSeg
  166.         InitSwapCount                   ;Initialize bytes LeftToSwap
  167.  
  168. ;Check for swapping to EMS or file
  169.         CMP     EmsAllocated,0          ;Check flag for EMS method
  170.         JZ      NotEms                  ;Jump if EMS not used
  171.         JMP     WriteE                  ;Swap to EMS
  172. NotEms: CMP     FileAllocated,0         ;Check flag for swap file method
  173.         JNZ     WriteF                  ;Swap to file
  174.         JMP     ESDone                  ;Exit if no swapping method set
  175.  
  176. ;Write to swap file
  177. WriteF: MovSeg  DS,CS                   ;DS = CS
  178.         InitSwapFile                    ;Seek to start of swap file
  179.         JNC     EF0                     ;Jump if success
  180.         JMP     ESDone                  ;Exit if error
  181. EF0:    SetSwapCount FileBlockSize      ;CX = bytes to write
  182.         MOV     DX,OFFSET FirstToSave   ;DS:DX -> start of region to save
  183.         DosCallAH 40h                   ;File write
  184.         JC      EF1                     ;Jump if write error
  185.         CMP     AX,CX                   ;All bytes written?
  186.         JZ      EF2                     ;Jump if so
  187. EF1:    JMP     ESDone                  ;Exit if error
  188. EF2:    NextBlock DS,FileBlockSize      ;Point DS to next block to write
  189.         JNZ     EF0                     ;Loop if bytes left to write
  190.         MOV     UsedEms,0               ;Flag we used swap file for swapping
  191.         JMP     SwapDone                ;Done swapping out
  192.  
  193. ;Write to EMS
  194. WriteE: MOV     ES,FrameSeg             ;ES -> page window
  195.         MOV     DX,EmsHandle            ;DX = handle of our EMS block
  196.         EmsCall 47h                     ;Save EMS context
  197.         XOR     BX,BX                   ;BX = initial logical page
  198.         MovSeg  DS,CS                   ;DS = CS
  199. EE0:    XOR     AL,AL                   ;Physical page 0
  200.         EmsCall 44h                     ;Map physical page
  201.         JZ      EE1                     ;Jump if success
  202.         JMP     ESDone                  ;Exit if error
  203. EE1:    SetSwapCount EmsPageSize        ;CX = Bytes to move
  204.         XOR     DI,DI                   ;ES:DI -> base of EMS page
  205.         MOV     SI,OFFSET FirstToSave   ;DS:SI -> region to save
  206.         MoveFast                        ;Move CX bytes from DS:SI to ES:DI
  207.         INC     BX                      ;Next logical page
  208.         NextBlock DS,EmsPageSize        ;Point DS to next page to move
  209.         JNZ     EE0                     ;Loop if bytes left to move
  210.         EmsCall 48h                     ;Restore EMS context
  211.         MOV     UsedEms,1               ;Flag we used EMS for swapping
  212.  
  213. ;Shrink memory allocated to this process
  214. SwapDone:MOV    AX,PrefixSegCS
  215.         MOV     ES,AX                   ;ES = segment of our memory block
  216.         DEC     AX
  217.         MOV     DS,AX                   ;DS = segment of memory control block
  218.         MOV     CX,DS:[0003h]           ;CX = current paragraphs owned
  219.         MOV     ParasWeHave,CX          ;Save current paragraphs owned
  220.         SetTempStack                    ;Switch to temporary stack
  221.         MOV     AX,OFFSET FirstToSave+15
  222.         MOV     CL,4
  223.         SHR     AX,CL                   ;Convert offset to paragraphs
  224.         ADD     BX,AX
  225.         SUB     BX,PrefixSegCS          ;BX = new paragraphs to keep
  226.         DosCallAH 4Ah                   ;SetBlock
  227.         JNC     EX0                     ;Jump if successful
  228.         JMP     EX5                     ;Swap back and exit
  229.  
  230. ;Set up parameters and call DOS Exec
  231. EX0:    MOV     AX,ES:[002Ch]           ;Get environment segment
  232.         MOV     EnvironSeg,AX
  233.         MovSeg  ES,CS                   ;ES = CS
  234.         LDS     SI,PathPtr              ;DS:SI -> path to execute
  235.         MOV     DI,OFFSET Path          ;ES:DI -> local ASCIIZ copy
  236.         CLD
  237.         LODSB                           ;Read current length
  238.         CMP     AL,63                   ;Truncate if exceeds space set aside
  239.         JB      EX1
  240.         MOV     AL,63
  241. EX1:    MOV     CL,AL
  242.         XOR     CH,CH                   ;CX = bytes to copy
  243.         REP     MOVSB
  244.         XOR     AL,AL
  245.         STOSB                           ;ASCIIZ terminate
  246.         LDS     SI,CmdPtr               ;DS:SI -> Command line to pass
  247.         MOV     DI,OFFSET CmdLine       ;ES:DI -> Local terminated copy
  248.         LODSB
  249.         CMP     AL,126                  ;Truncate command if exceeds space
  250.         JB      EX2
  251.         MOV     AL,126
  252. EX2:    STOSB
  253.         MOV     CL,AL
  254.         XOR     CH,CH                   ;CX = bytes to copy
  255.         REP     MOVSB
  256.         MOV     AL,0DH                  ;Terminate with ^M
  257.         STOSB
  258.         MovSeg  DS,CS                   ;DS = CS
  259.         MOV     SI,OFFSET CmdLine
  260.         MOV     CmdLinePtr.ofst,SI
  261.         MOV     CmdLinePtr.segm,DS      ;Store pointer to command line
  262.         INC     SI
  263.         MOV     DI,OFFSET FileBlock1
  264.         MOV     FilePtr1.ofst,DI
  265.         MOV     FilePtr1.segm,ES        ;Store pointer to filename 1, if any
  266.         DosCallAX 2901h                 ;Parse FCB
  267.         MOV     DI,OFFSET FileBlock2
  268.         MOV     FilePtr2.ofst,DI
  269.         MOV     FilePtr2.segm,ES        ;Store pointer to filename 2, if any
  270.         DosCallAX 2901h                 ;Parse FCB
  271.         MOV     DX,OFFSET Path
  272.         MOV     BX,OFFSET EnvironSeg
  273.         DosCallAX 4B00h                 ;Exec
  274.         JC      EX3                     ;Jump if error in DOS call
  275.         XOR     AX,AX                   ;Return zero for success
  276. EX3:    MOV     Status,AX               ;Save DOS error code
  277.  
  278. ;Set up temporary stack and reallocate original memory block
  279.         SetTempStack                    ;Set up temporary stack
  280.         MOV     ES,PrefixSegCS
  281.         MOV     BX,ParasWeHave
  282.         DosCallAH 4Ah                   ;SetBlock
  283.         JNC     EX4                     ;Jump if no error
  284.         HaltWithError 0FFh              ;Must halt if failure here
  285. EX4:    InitSwapCount                   ;Initialize LeftToSwap
  286.  
  287. ;Check which swap method is in use
  288. EX5:    CMP     UsedEms,0
  289.         JZ      ReadF                   ;Jump to read back from file
  290.         JMP     ReadE                   ;Read back from EMS
  291.  
  292. ;Read back from swap file
  293. ReadF:  MovSeg  DS,CS                   ;DS = CS
  294.         InitSwapFile                    ;Seek to start of swap file
  295.         JNC     EF3                     ;Jump if we succeeded
  296.         HaltWithError 0FEh              ;Must halt if failure here
  297. EF3:    SetSwapCount FileBlockSize      ;CX = bytes to read
  298.         MOV     DX,OFFSET FirstToSave   ;DS:DX -> start of region to restore
  299.         DosCallAH 3Fh                   ;Read file
  300.         JNC     EF4                     ;Jump if no error
  301.         HaltWithError 0FEh              ;Must halt if failure here
  302. EF4:    CMP     AX,CX
  303.         JZ      EF5                     ;Jump if full block read
  304.         HaltWithError 0FEh              ;Must halt if failure here
  305. EF5:    NextBlock DS,FileBlockSize      ;Point DS to next page to read
  306.         JNZ     EF3                     ;Jump if bytes left to read
  307.         JMP     ESDone                  ;We're done
  308.  
  309. ;Copy back from EMS
  310. ReadE:  MOV     DX,EmsHandleCS          ;DX = handle of our EMS block
  311.         EmsCall 47h                     ;Save EMS context for next time
  312.         MOV     DS,FrameSegCS           ;DS -> page window
  313.         XOR     BX,BX                   ;BX = initial logical page
  314.         MovSeg  ES,CS                   ;ES = CS
  315. EE3:    XOR     AL,AL                   ;Physical page 0
  316.         EmsCall 44h                     ;Map physical page
  317.         JZ      EE4                     ;Jump if success
  318.         HaltWithError 0FDh              ;Must halt if failure here
  319. EE4:    SetSwapCount EmsPageSize        ;CX = Bytes to move
  320.         XOR     SI,SI                   ;DS:SI -> base of EMS page
  321.         MOV     DI,OFFSET FirstToSave   ;ES:DI -> region to restore
  322.         MoveFast                        ;Move CX bytes from DS:SI to ES:DI
  323.         INC     BX                      ;Next logical page
  324.         NextBlock ES,EmsPageSize        ;Point ES to next page to move
  325.         JNZ     EE3                     ;Jump if so
  326.         EmsCall 48h                     ;Restore EMS context
  327.  
  328. ESDone: CLI                             ;Switch back to original stack
  329.         MOV     SS,SaveSS
  330.         MOV     SP,SaveSP
  331.         STI
  332.         MOV     AX,SEG DATA
  333.         MOV     DS,AX                   ;Restore DS
  334.         MOV     AX,Status               ;Return status
  335.         POP     BP
  336.         RET     8                       ;Remove parameters and return
  337. ExecWithSwap    ENDP
  338. ;-----------------------------------------------------------------------------
  339. ;Label marks first location to swap
  340.         EVEN
  341. FirstToSave:
  342. ;-----------------------------------------------------------------------------
  343. ;function AllocateSwapFile : Boolean;
  344. AllocateSwapFile PROC NEAR
  345.         MOV     CX,FileAttr             ;Attribute for swap file
  346.         MOV     DX,OFFSET SwapName+1    ;DS:DX -> ASCIIZ swap name
  347.         DosCallAH 3Ch                   ;Create file
  348.         MOV     FileHandle,AX           ;Save handle assuming success
  349.         MOV     AL,0                    ;Assume failure
  350.         JC      ASDone                  ;Failed if carry set
  351.         INC     AL                      ;Return true for success
  352. ASDone: RET
  353. AllocateSwapFile ENDP
  354. ;-----------------------------------------------------------------------------
  355. ;procedure DeallocateSwapFile;
  356. DeallocateSwapFile PROC NEAR
  357.         MOV     BX,FileHandle           ;Handle of swap file
  358.         DosCallAH 3Eh                   ;Close file
  359.         XOR     CX,CX                   ;Normal attribute
  360.         MOV     DX,OFFSET SwapName+1    ;DS:DX -> ASCIIZ swap name
  361.         DosCallAX 4301h                 ;Set file attribute
  362.         DosCallAH 41h                   ;Delete file
  363.         RET
  364. DeallocateSwapFile ENDP
  365. ;-----------------------------------------------------------------------------
  366. ;function EmsInstalled : Boolean;
  367. EmsInstalled    PROC FAR
  368.         PUSH    DS
  369.         MovSeg  DS,CS                   ;DS = CS
  370.         MOV     DX,OFFSET EmsDevice     ;DS:DX -> EMS driver name
  371.         DosCallAX 3D02h                 ;Open for read/write
  372.         POP     DS
  373.         MOV     BX,AX                   ;Save handle in case one returned
  374.         MOV     AL,0                    ;Assume FALSE
  375.         JC      EIDone
  376.         DosCallAH 3Eh                   ;Close file
  377.         MOV     AL,1                    ;Return TRUE
  378. EIDone: RET
  379. EmsInstalled    ENDP
  380. ;-----------------------------------------------------------------------------
  381. ;function EmsPageFrame : Word;
  382. EmsPageFrame    PROC FAR
  383.         EmsCall 41h                     ;Get page frame
  384.         MOV     AX,BX                   ;AX = segment
  385.         JZ      EPDone                  ;Done if Error = 0
  386.         XOR     AX,AX                   ;Else segment = 0
  387. EPDone: RET
  388. EmsPageFrame    ENDP
  389. ;-----------------------------------------------------------------------------
  390. ;function AllocateEmsPages(NumPages : Word) : Word;
  391. AllocateEmsPages PROC FAR
  392.         MOV     BX,SP                   ;Set up stack frame
  393.         MOV     BX,SS:[BX+4]            ;BX = NumPages
  394.         EmsCall 43h                     ;Allocate EMS
  395.         MOV     AX,DX                   ;Assume success
  396.         JZ      APDone                  ;Done if not 0
  397.         MOV     AX,0FFFFh               ;$FFFF for failure
  398. APDone: RET     2                       ;Remove parameter and return
  399. AllocateEmsPages ENDP
  400. ;-----------------------------------------------------------------------------
  401. ;procedure DeallocateEmsHandle(Handle : Word);
  402. DeallocateEmsHandle PROC FAR
  403.         MOV     BX,SP                   ;Set up stack frame
  404.         MOV     DX,SS:[BX+4]            ;DX = Handle
  405.         EmsCall 45h                     ;Deallocate EMS
  406.         RET     2                       ;Remove parameter and return
  407. DeallocateEmsHandle ENDP
  408. ;-----------------------------------------------------------------------------
  409. ;function DefaultDrive : Char;
  410. DefaultDrive    PROC FAR
  411.         DosCallAH 19h                   ;Get default drive
  412.         ADD     AL,'A'                  ;Convert to character
  413.         RET
  414. DefaultDrive    ENDP
  415. ;-----------------------------------------------------------------------------
  416. ;function DiskFree(Drive : Byte) : LongInt;
  417. DiskFree        PROC FAR
  418.         MOV     BX,SP                   ;Set up stack frame
  419.         MOV     DL,SS:[BX+4]            ;DL = Drive to check
  420.         DosCallAH 36h                   ;Get disk space
  421.         MOV     DX,AX                   ;Return 0FFFFFFFFh for failure
  422.         CMP     AX,0FFFFh               ;Bad drive number?
  423.         JZ      DFDone                  ;Jump if so
  424.         MUL     CX                      ;AX = bytes/cluster
  425.         MUL     BX                      ;DX:AX = bytes free
  426. DFDone: RET     2                       ;Remove parameter and return
  427. DiskFree        ENDP
  428. ;-----------------------------------------------------------------------------
  429. CODE    ENDS
  430.         END
  431.